package crazyjava;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class ThreadCondition {

	/**
	 * @param args
	 */
	public static void main(String[] args) {

		printThread(5, 5);
	}

	static void printThread(int num, final int times) {
		final ThreadDemo td = new ThreadDemo(num, times);
		for (int i = 1; i <= 5; i++) {
			final int threadNum = i;
			new Thread(new Runnable() {

				public void run() {

					td.ThreadRun(threadNum, times);
				}
			}).start();
		}
	}

}

class ThreadDemo {
	private int maxThread;
	private int tag = 1;
	private List<Condition> conditions;
	Lock lock;

	public ThreadDemo(int ThreadNum, int times) {
		conditions = new ArrayList<Condition>();
		lock = new ReentrantLock();
		maxThread = ThreadNum;
		for (int i = 0; i < ThreadNum; i++) {
			conditions.add(lock.newCondition());
		}
	}

	public void ThreadRun(int threadNum, int times) {
		lock.lock();
		try {
			int m = 1;
			while (m <= times) {
				if (threadNum != tag) {
					try {
						conditions.get(threadNum - 1).await();
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
				try {
					Thread.sleep(100);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				System.out.println("The " + threadNum + " Thread "
						+ "is running the " + m);
				if (tag == maxThread) {
					tag = 1;
				} else {
					tag++;
				}
				int other = threadNum;
				if (threadNum == maxThread) {
					other = 0;
				}
				m++;
				conditions.get(other).signal();
			}
		} finally {
			lock.unlock();
		}
	}
}
